#include "mainwindow.h"
#include "QtGui"
#include <qcheckbox.h>
#include <QDebug>

using namespace cv;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    isShow = 1;
    isExit = 0;
    QCheckBox *cb = new QCheckBox(tr("open"));
    this->setCentralWidget(cb);
    this->show();
    connect(cb, SIGNAL(stateChanged(int)), SLOT(changework(int)));
    connect(this, SIGNAL(destroyed()), this, SLOT(Exit()));
    work();
}


MainWindow::~MainWindow()
{

}
void MainWindow::Exit()
{
    qDebug() << isExit;
    isExit = 1;
}

void MainWindow::changework(int state)
{
    isShow = state;
    Mat m;
    m/= 0;
}

inline int suitPoint(int x, int goal, int flag)
{
    if(flag)
    {
        if(x < goal)
            x = goal;
    }
    else if(x > goal)
        x = goal;
    return x;
}

void MainWindow::findContours(IplImage *src)
{
      IplImage *dst;
      //src = cvLoadImage("pic.jpg", -1);
      dst = cvCreateImage(cvGetSize(src), 8, 3);
      CvMemStorage *storage = cvCreateMemStorage();
      CvSeq *contour = NULL, *hull = NULL;
      //find contours 8-connects or 4-connects
      CvContourScanner scanner = cvStartFindContours(src, storage);
      cvDrawContours(dst, contour, CV_RGB(255, 0, 0), CV_RGB(0, 255, 0), 0);
      while((contour = cvFindNextContour(scanner))!= NULL)
      {
          //set black background
          cvDrawContours(dst, contour, CV_RGB(255, 0, 0), CV_RGB(0, 255, 0), 0);
        ///  std::cout << cvCheckContourConvexity(contour) << std::endl;
          hull = cvConvexHull2(contour, 0, CV_CLOCKWISE, 0);
          CvPoint pt0 = **(CvPoint**) cvGetSeqElem(hull, hull->total - 1);
          for(int i = 0; i < hull->total; ++i)
          {
              CvPoint pt1 = **(CvPoint**)cvGetSeqElem(hull, i);
              cvLine(dst, pt0, pt1, CV_RGB(0, 0, 255));
              pt0 = pt1;
          }
          CvSeq *defect = cvConvexityDefects(contour, hull);
          for(int i = 0; i < defect->total; ++i)
          {
              CvConvexityDefect df = *(CvConvexityDefect*)cvGetSeqElem(defect, i);
              cvCircle(dst, *df.start, 2, CV_RGB(255, 255, 0), -1);
              cvCircle(dst, *df.end, 2, CV_RGB(255, 255, 0), -1);
              cvCircle(dst, *df.depth_point, 2, CV_RGB(0, 255, 255), -1);
          }
          cvShowImage("dst", dst);
          cvShowImage("src", src);
      }

      cvWaitKey(20);
}

uchar MainWindow::detectCode(CvPoint point, int width, int height)
{
    int x = point.x * 3 / height;
    int y = point.y * 3 / width;
    qDebug()<< x * 3 + y;
}

int MainWindow::otsu(IplImage *src, IplImage *dst)
{
    int width = src->width;
    int height = src->height;
    IplImage *imgYCrCb = cvCreateImage(cvSize(width, height),
                                       src->depth, src->nChannels);
    cvCvtColor(src, imgYCrCb, CV_BGR2YCrCb);
    cvSplit(imgYCrCb, 0, dst, 0, 0);
    cvFlip(dst, dst, 1);
    float p[256] = {0};
    uchar *data = (uchar *)dst->imageData;
    for(int i = 0; i < height; i++)
        for(int j = 0; j < width; j++)
            p[data[i*dst->widthStep + j]] ++;
    float w0, w1, u0, u1, deltaMax, deltaTmp;
    float w[256] = {0}, tmp[256] = {0};
    w[0] = p[0];
    for(int i = 1; i < 256; i++)
    {
        w[i] = p[i] + w[i-1];
        tmp[i] = i * p[i] + tmp[i-1];
    }
    int threshold = 0;
    for(int i = 0; i < 255; i++)
    {
        w0 = w[i];
        w1 = w[255] - w[i];
        u0 = tmp[i]/w[i];
        u1 = (tmp[255] - tmp[i])/(w[255] - w[i]);
        deltaTmp = w0 * w1 *(u0 - u1) * (u0 - u1);
        if(deltaTmp > deltaMax)
        {
            deltaMax = deltaTmp;
            threshold = i;
        }
    }
    cvThreshold(dst, dst, threshold, 255, CV_THRESH_BINARY);
    IplImage * temp = cvCreateImage(cvGetSize(dst), 8,1);
    cvMorphologyEx(dst, dst, temp, NULL, CV_MOP_CLOSE, 1);
    cvMorphologyEx(dst, dst, temp, NULL, CV_MOP_OPEN, 1);
    cvShowImage("dst", dst);
    cvReleaseImage(&temp);
    cvReleaseImage(&imgYCrCb);
    return threshold;
}


void MainWindow::work()
{
    camera = cvCreateCameraCapture(CV_CAP_ANY);
  //  vec.clear();
    if(!camera)return;
    IplImage *Icr;
    IplImage *src;
    src = cvCreateImage(cvSize(480, 480), 8, 3);
    Icr = cvCreateImage(cvSize(480, 480), 8, 1);
    while(1)
    {
        if(isExit) return;
        IplImage *I = cvQueryFrame(camera);
        if(!I) continue;
        cvResize(I, src);
        if(isShow)
        {
            otsu(src, Icr);
            cvShowImage("dst", Icr);
            CvPoint point = det.Detect(Icr, Icr);
            if(point.x == -1) continue;
            //findContours(Icr);
            detectCode(point, Icr->width, Icr->height);
            //char ch = cvWaitKey(5);
            //if(ch == 'y')
              //  cvSaveImage("pic.jpg", Icr);
        }
        else cvDestroyAllWindows();
      //  cvWaitKey(10);
    }
}


